/**
 * 创建 threejs 四大天王
 * 场景、相机、渲染器、控制器
 */

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

export class Basic {
  public scene: THREE.Scene
  public camera: THREE.PerspectiveCamera
  public renderer: THREE.WebGLRenderer
  public controls: OrbitControls
  public dom: HTMLElement

  constructor(dom: HTMLElement) {
    this.dom = dom
    this.initScenes()
    this.setControls()
  }

  /**
   * 初始化场景
   */
  initScenes() {
    this.scene = new THREE.Scene()

    this.camera = new THREE.PerspectiveCamera(
      45,
      window.innerWidth / window.innerHeight,
      1,
      100000
    )
    this.camera.position.set(0, 30, -250)

    this.renderer = new THREE.WebGLRenderer({
      alpha: true, // 透明
      antialias: true, // 抗锯齿
    })
    this.renderer.setPixelRatio(window.devicePixelRatio) // 设置屏幕像素比
    this.renderer.setSize(window.innerWidth, window.innerHeight) // 设置渲染器宽高
    // this.renderer.domElement.addEventListener('click', this.choose)
    this.dom.appendChild(this.renderer.domElement) // 添加到dom中

    // 鼠标事件（点击标记的点的事件）
    const mouseClick = (event) => {
      console.log('当前-------坐标', this.camera.position)
      event.preventDefault()
      // 声明 raycaster 和 mouse 变量
      const raycaster = new THREE.Raycaster()
      const mouse = new THREE.Vector2()

      // 通过鼠标点击位置,计算出 raycaster 所点的位置,以屏幕为中心点,范围 -1 到 1
      const getBoundingClientRect = this.dom.getBoundingClientRect()
      mouse.x =
        ((event.clientX - getBoundingClientRect.left) / this.dom.offsetWidth) *
          2 -
        1
      mouse.y =
        -((event.clientY - getBoundingClientRect.top) / this.dom.offsetHeight) *
          2 +
        1
      // mouse.x = this.dom.offsetWidth / 2;
      // mouse.y = -this.dom.offsetHeight / 2;
      console.log('mouse: ', mouse)

      //通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置
      raycaster.setFromCamera(mouse, this.camera)
      // 获取与射线相交的对象数组，其中的元素按照距离排序，越近的越靠前
      const intersects = raycaster.intersectObjects(this.scene.children)
      // 获取点击对象的值
      let name
      for (let i = 0; i < intersects.length; i++) {
        if (intersects[i].object.type == 'Sprite') {
          const countryName = intersects[i].object.name // 国家
          // let V3 = intersects[i].object.position; // 三维坐标
          if (countryName != '') {
            // divPop(countryName, V3); //调用弹窗函数
            console.log('countryName: ', countryName)
            name = countryName
          }
        }
      }
      // if (intersects.length > 0) {
      //   if (intersects[0].object.children.length > 0) {
      //     // console.log('name: ', intersects[0].object.children[0].name);
      //     alert(intersects[0].object.children[0].name)
      //   }
      // }

      // 这里追加一个方法，用来调用外部的方法
      // const testC = window['chartClick'] // 这里的chartClick是外部定义的方法 临时测试
      // const testC1 = window['chartClick1'] // 这里的chartClick是外部定义的方法 临时测试
      // testC(name)
      // testC1(name)
    }
    this.renderer.domElement.addEventListener('click', mouseClick)
  }

  /**
   * 设置控制器
   */
  setControls() {
    // 鼠标控制      相机，渲染dom
    this.controls = new OrbitControls(this.camera, this.renderer.domElement)

    this.controls.autoRotateSpeed = 3
    // 使动画循环使用时阻尼或自转 意思是否有惯性
    this.controls.enableDamping = false
    // 动态阻尼系数 就是鼠标拖拽旋转灵敏度
    this.controls.dampingFactor = 0.05
    // 是否可以缩放
    this.controls.enableZoom = true
    // 设置相机距离原点的最远距离
    this.controls.minDistance = 100
    // 设置相机距离原点的最远距离
    this.controls.maxDistance = 200
    // 是否开启右键拖拽
    this.controls.enablePan = false
  }
}
